package com.github.baichuan.application.scaffold.rest.jpa.identity;

import com.github.baichuan.application.scaffold.rest.domain.organization.Org;
import com.github.baichuan.application.scaffold.rest.domain.application.Application;
import com.github.baichuan.application.scaffold.rest.domain.authorization.Role;
import com.github.baichuan.application.scaffold.rest.domain.identity.ApplicationMember;
import com.github.baichuan.application.scaffold.rest.domain.identity.Member;
import jakarta.persistence.criteria.*;
import lombok.Builder;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;

@Builder
public class ApplicationMemberSpecification implements Specification<ApplicationMember> {
    private Application application;
    private ApplicationMember applicationMember;
    private String memberType;
    /**
     * 登录名/姓名/手机/邮箱
     */
    private String keyword;
    private Short roleId;

    private String orgBranch;


    @Override
    public Predicate toPredicate(Root<ApplicationMember> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) {
        if (application == null) {
            throw new IllegalStateException("application is null");
        }
        if (applicationMember == null) {
            throw new IllegalStateException("memberUid is null");
        }
        Predicate restrictions = builder.equal(root.get("application"), application);
        if (ObjectUtils.isNotEmpty(applicationMember) && !applicationMember.getMemberType().equals("ADMIN")) {
            Join<ApplicationMember, Org> org = root.join("org");
            restrictions = builder.and(restrictions,
                    builder.like(org.get("branch"), applicationMember.getOrg().getBranch() + "%"));
        }
        Join<ApplicationMember, Member> member = root.join("member");

        if (StringUtils.isNotBlank(keyword)) {
            String value = "%" + keyword.trim() + "%";
            Predicate likeLoginName = builder.like(member.get("loginName"), value);
            Predicate likeName = builder.like(member.get("name"), value);
            Predicate likeEmail = builder.like(member.get("email"), value);
            Predicate likeMobile = builder.like(member.get("mobile"), value);
            restrictions = builder.and(restrictions, builder.or(likeLoginName, likeName, likeEmail, likeMobile));
        }

        if (StringUtils.isNotBlank(memberType)) {
            restrictions = builder.and(restrictions, builder.equal(root.get("memberType"), memberType));
        }

        if (StringUtils.isNotBlank(orgBranch)) {
            Join<ApplicationMember, Org> join = root.join("org");
            restrictions = builder.and(restrictions, builder.like(join.get("branch"), orgBranch + "%"));
        }

        if (roleId != null) {
            Join<ApplicationMember, Role> role = root.join("roles");
            restrictions = builder.and(restrictions, builder.equal(role.get("id"), roleId));
        }

        return restrictions;
    }
}
